package com.gupaoedu.task.pattern.prototype.originalcode;

/**
 * @author djl
 * @Title: Client
 * @Description: TODO
 * @date 2019/3/30
 */
public class Client {

    public static void main(String[] args) throws CloneNotSupportedException{
/*
//写法一 三份简历需要三次实例化
        Resume a = new Resume("张三");
        a.SetPersonalInfo("男", "29");
        a.SetWorkExperience("2011-2018", "XX公司");

        Resume b = new Resume("张三");
        b.SetPersonalInfo("男", "29");
        b.SetWorkExperience("2011-2018", "XX公司");

        Resume c = new Resume("张三");
        c.SetPersonalInfo("男", "29");
        c.SetWorkExperience("2011-2018", "XX公司");

        a.Display();
        b.Display();
        c.Display();


//写法二 其实是传引用 而不是传值 这样做就如同是在b纸张和c纸张上写着简历在a处一样 没有实际的内容
        Resume a = new Resume("张三");
        a.SetPersonalInfo("男", "29");
        a.SetWorkExperience("2011-2018", "XX公司");

        Resume b = a;

        Resume c = a;

        a.Display();
        b.Display();
        c.Display();
*/



        // 原型模式(Clone克隆)进行重构
        //clone()方法是这样 如果字段是值类型的
        // 则对该字段执行逐位复制 如果字段是引用类型
        // 则复制引用但不复制引用的对象
        // 因此 原始对象及其复本引用同一对象
        // 就是说如果简历类中有对象引用 那么引用的对象数据是不会被克隆过来的
      /*Resume a = new Resume("张三");
        a.SetPersonalInfo("男", "29");
        a.SetWorkExperience("2011-2018", "XX公司");

        Resume b = (Resume)a.Clone();
        b.SetWorkExperience("2011-2018", "YY企业");

        Resume c = (Resume)a.Clone();
        c.SetPersonalInfo("男", "24");

        a.Display();
        b.Display();
        c.Display();*/

        //三个引用都指向了同一个对象
        // 这叫做浅克隆
        // 被复制对象的所有变量都含有与原来的对象相同的值
        // 而所有的对其他对象的引用都仍然指向原来的对象


        //深克隆把引用对象的变量指向复制过的新对象
        // 而不是原有的被引用的对象
       Resume a = new Resume("张三");
        a.SetPersonalInfo("男", "29");
        a.SetWorkExperience("2011-2018", "XX公司");

        Resume b = (Resume)a.Clone();
        b.SetWorkExperience("2011-2018", "YY企业");

        Resume c = (Resume)a.Clone();
        c.SetPersonalInfo("男", "24");
        c.SetWorkExperience("2011-2018", "ZZ企业");

        a.Display();
        b.Display();
        c.Display();
        //原型模式 用原型实例指定创建对象的种类
        // 并且通过拷贝这些原型创建新的对象
        //原型模式其实就是从一个对象再创建另外一个可定制的对象
        // 而且不需知道任何创建的细节 实现Cloneable这个接口就可以完成原型模式
        //一般在初始化的信息不发生变化的情况下
        // 克隆是最好的办法 既隐藏了对象创建的细节 又对性能是大大的提高
        // 它等于是不用重新初始化对象 而是动态地获得对象运行时的状态
        //缺点 原型模式无法和单例模式组合使用 使用原型模式时不能有final对象 浅克隆
    }


}
